#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>

#define MAP_SIZE 4096
#define MAP_MASK 4095

int get_gpio_num(int group, int pin)
{
	return 496 - group * 16 + pin;
}

int check_gpio_dir(int num)
{
	char filepath[256] = { '\0' };
	
	// Get full directory name
	snprintf(filepath, 256, "/sys/class/gpio/gpio%d", num);

	return access(filepath, F_OK);
}

int set_gpio_attr(int num, const char *attr, const char *value)
{
	char filepath[256] = { '\0' };
	int fd;

	// Get full directory name
	snprintf(filepath, 256, "/sys/class/gpio/gpio%d/%s", num, attr);

	printf("Write \"%s\" into %s\n", value, filepath);
	fd = open(filepath, O_WRONLY);
	write(fd, value, strlen(value));

	close(fd);
}

int main(int argc, char *argv[])
{
	int i, fnum;
	char gpio_num[10] = { '\0' };
	int pins[4] = {};
	int wait_ms = 5000; // 5ms

	int export_fd;

	pins[0] = get_gpio_num(4, 11);
	pins[1] = get_gpio_num(5, 12);
	pins[2] = get_gpio_num(5, 13);
	pins[3] = get_gpio_num(5, 14);

	if (argc > 1) {
		wait_ms = atoi(argv[1]);
	}

	for (i = 0; i < 4; i++) {
		fnum = pins[i];
		if (check_gpio_dir(fnum)) {
			export_fd = open("/sys/class/gpio/export", O_WRONLY);
			snprintf(gpio_num, 10, "%d", fnum);
			write(export_fd, gpio_num, strlen(gpio_num));
		}

		set_gpio_attr(fnum, "direction", "out");
		set_gpio_attr(fnum, "edge", "gpio");
		set_gpio_attr(fnum, "value", "0");
	}

	i = 0;

	while (1) {
		fnum = pins[i % 4];
		set_gpio_attr(fnum, "value", "0");
		
		usleep(wait_ms);

		fnum = pins[(i + 1) % 4];
		set_gpio_attr(fnum, "value", "1");

		i++;
	}

	return 0;
}

